import { MessageDialog, ValuesDialog, ValueType } from "../functions/domdialog/valuesdialog.js";
import { Editor } from "./pixeleditor.js";
import * as DOM from "../functions/dom/domtool.js";
import { RectRange } from "../functions/image/rect.js";
import { DrawTool, DrawToolCenter, Model_Tool } from "./drawtool.js";
import { IO } from "../common/io.js";
import { ImgTool } from "../functions/image/image.js";
export class PixelEditor_Function {

    private static InitToolbar(toolbar: DOM.Toolbar) {
        toolbar.addButton("media/pen.png", "pencil", "铅笔");
        toolbar.addButton("media/line.png", "drawline", "画线");
        toolbar.addButton("media/rect.png", "drawrect", "画方");
        toolbar.addButton("media/circle.png", "drawcircle1", "中心点画圆");
        toolbar.addButton("media/circle2.png", "drawcircle2", "对角画圆");
        toolbar.addButton("media/circle_out.png", "drawcircle_out", "画矩形外接圆");

        toolbar.addButton("media/select.png", "select", "选取");
        toolbar.addButton("media/move.png", "move", "移动选区");
        toolbar.addButton("media/rotate.png", "rotate", "旋转选区");

        toolbar.addButton("media/pick.png", "pick", "拾色器");
        toolbar.addButton("media/fill.png", "fill", "填充");
        toolbar.addButton("media/model.png", "model", "摆放模板-coming...");


        toolbar.addButton("media/earse.png", "earse", "橡皮擦");
        toolbar.addButton("media/filltran.png", "filltran", "填充透明色");

        toolbar.addButton("media/picklayer.png", "picklayer", "选取层-coming...", "#c33");

        // toolbar.addButton("media/pick.png", "pick", "拾色器");
        // 


    }
    private static select_All(editor: Editor): void {
        let all = new RectRange(0, 0, editor.drawCanvas.getWidth() - 1, editor.drawCanvas.getHeight() - 1);
        editor.drawCanvas.getCurrentLayer().Select(all)
    }
    private static select_Desel(editor: Editor): void {
        editor.drawCanvas.getCurrentLayer().Select_Cancel();
        editor.drawCanvas.RePaint();
    }
    private static async select_C(editor: Editor) {
        let b = await editor.drawCanvas.getCurrentLayer().Select_CopyDataToBlob();
        await navigator.clipboard.write([new ClipboardItem({ "image/png": b })]);
        //let json = editor.drawCanvas.getCurrentLayer().Select_CopyDataToJson();
        //await navigator.clipboard.writeText(JSON.stringify(json));
    }
    private static async select_V(editor: Editor) {
        let citems = await navigator.clipboard.read();
        for (var i = 0; i < citems.length; i++) {
            let t = citems[i].types;
            for (var j = 0; j < t.length; j++) {
                console.log("clip type=" + citems[i].types[j]);
                if (citems[i].types[j] == "image/png") {
                    let imgb = await citems[i].getType("image/png");
                    let url = URL.createObjectURL(imgb);

                    let img = await ImgTool.Url2ImgAsync(url);

                    editor.drawCanvas.getCurrentLayer().applySelectData();
                    editor.drawCanvas.getCurrentLayer().Select_FromImg(img);
                    let tag = editor.toolbar.getPickTag();
                    DrawToolCenter.GetDrawTool(tag).OnSet();


                    editor.drawCanvas.RePaint();
                    return;
                }
            }
        }

        let txt = await navigator.clipboard.readText();
        try {
            let json = JSON.parse(txt);
            if (json["type"] == "imageblock") {
                editor.drawCanvas.getCurrentLayer().applySelectData();
                editor.drawCanvas.getCurrentLayer().Select_FromJson(json);
                let tag = editor.toolbar.getPickTag();

                DrawToolCenter.GetDrawTool(tag).OnSet();

                editor.drawCanvas.RePaint();
            }
        }
        catch
        {
            console.log("Ctrl+V error.");
        }

    }
    private static async select_X(editor: Editor) {
        let json = editor.drawCanvas.getCurrentLayer().Select_CutDataToJson();
        await navigator.clipboard.writeText(JSON.stringify(json));
        editor.drawCanvas.RePaint();
    }

    private static async history_Z(editor: Editor) {
        editor.history.GoLast();
    }
    private static async history_Y(editor: Editor) {
        editor.history.GoNext();
    }
    private static async ResetModels(editor: Editor, path: string) {
        editor.toolbox_model_bar._root.parentElement.style.overflowX = "hidden";
        editor.toolbox_model_bar._root.parentElement.style.overflowY = "scroll"; 
        editor.toolbox_model_bar.btnsize = 36;
        editor.toolbox_model_bar.clearButton();
        try {
            let files = await IO.FindFile(path, 5);
            for (var i = 0; i < files.length; i++) {
                let f = files[i];
                //限制下文件容量，模板文件就不可能大
                if (f.name.includes(".png") && f.size < 100 * 1024) {
                    console.log("load file:" + f.name);
                    let bin = await IO.LoadBinaryFile(f.name);
                    console.log("load file succ.");
                    //let img = await ImgTool.Bin2ImgAsync(bin);
                    let url = ImgTool.Bin2Url(bin);
                    editor.toolbox_model_bar.addButton(url, f.name, f.name);
                }
            }
        }
        catch (e) {
            let d = new MessageDialog("error", [{ "txt": "error:" + e, align: "center" }]);
            await d.Show();
        }
    }
    static InitFunc(editor: Editor) {
        this.InitToolbar(editor.toolbar);
        //this.group_func.SetTitle("保存功能");
        window.addEventListener("keydown", (e) => {
            if (e.key == "s" && (e.metaKey || e.ctrlKey)) {
                e.preventDefault();
                editor._save();
            }
            if (e.key == "a" && (e.metaKey || e.ctrlKey)) {
                //权限
                e.preventDefault();
                this.select_All(editor);
            }
            if (e.key == "d" && (e.metaKey || e.ctrlKey)) {
                //取消选区
                e.preventDefault();
                this.select_Desel(editor);
            }
            if (e.key == "c" && (e.metaKey || e.ctrlKey)) {
                //复制
                e.preventDefault();
                this.select_C(editor);
            }
            if (e.key == "x" && (e.metaKey || e.ctrlKey)) {
                //剪切
                e.preventDefault();
                this.select_X(editor);
            }
            if (e.key == "v" && (e.metaKey || e.ctrlKey)) {
                //粘贴
                e.preventDefault();
                this.select_V(editor);
            }
            if (e.key == "z" && (e.metaKey || e.ctrlKey)) {
                //撤销
                e.preventDefault();
                this.history_Z(editor);
            }
            if (e.key == "y" && (e.metaKey || e.ctrlKey)) {
                //重做
                e.preventDefault();
                this.history_Y(editor);
            }
        });
        // this.group_func.AddChild(new DOM.Button("保存", async () => {
        //     this._save();
        // }));

        editor.menu = new DOM.Menu();
        editor.menu.AddItem("保存 CTRL+S", () => {
            editor._save();
        });
        editor.menu.AddItem("_", null);
        editor.menu.AddItem("参考线-隐藏", (btn: HTMLElement) => {
            editor.drawCanvas.op_grid = !editor.drawCanvas.op_grid;
            editor.drawCanvas.RePaint();
            btn.textContent = editor.drawCanvas.op_grid ? "参考线-隐藏" : "参考线-显示";
        });
        editor.menu.AddItem("加载参考图(背景,不保存)", async () => {
            let d = new ValuesDialog("加载参考图", [{ "name": "文件名", "type": ValueType.STRING, "defvalue": "d:\\1.png" }]);
            let r = await d.Show();
            if (r != null) {
                try {
                    let file = await IO.LoadBinaryFile(r[0]);
                    let img = await ImgTool.Bin2ImgAsync(file);
                    editor.drawCanvas.op_backlayer.getContext().clearRect(0, 0, editor.drawCanvas.getWidth(), editor.drawCanvas.getHeight());
                    editor.drawCanvas.op_backlayer.getContext().drawImage(img, 0, 0);
                    editor.drawCanvas.op_backlayer.updateBitmap();
                } catch (e) {
                    console.log("error:" + e);
                }
            }

        });

        editor.menu.AddItem("参考图-隐藏", (btn: HTMLElement) => {
            editor.drawCanvas.op_backpicshow = !editor.drawCanvas.op_backpicshow;
            editor.drawCanvas.RePaint();
            btn.textContent = editor.drawCanvas.op_backpicshow ? "参考图-隐藏" : "参考图-显示";
        });

        editor.menu.AddItem("_", null);
        editor.menu.AddItem("选区-全选 CTRL+A", () => {
            this.select_All(editor);
        });
        editor.menu.AddItem("选区-取消选区 CTRL+D", () => {
            this.select_Desel(editor);
        });
        editor.menu.AddItem("选区-复制 CTRL+C", () => {
            this.select_C(editor);
        });
        editor.menu.AddItem("选区-粘贴 CTRL+V", () => {
            this.select_V(editor);
        });
        editor.menu.AddItem("选区-剪切 CTRL+X", () => {
            this.select_X(editor);
        });
        editor.menu.AddItem("_", null);
        editor.menu.AddItem("加载模板图片", async () => {
            let d = new ValuesDialog("加载模板图片", [
                { name: "图片路径", defvalue: "pic", type: ValueType.STRING }
            ])
            let r = await d.Show();
            if (r != null) {
                this.ResetModels(editor, r[0]);
            }
        });
        editor.menu.AddItem("模板对齐/1px", async () => {
            (DrawToolCenter.GetDrawTool("model") as Model_Tool).Align = 1;
        })
        editor.menu.AddItem("模板对齐/16px", async () => {
            (DrawToolCenter.GetDrawTool("model") as Model_Tool).Align = 16;
        })
        editor.menu.AddItem("模板对齐/32px", async () => {
            (DrawToolCenter.GetDrawTool("model") as Model_Tool).Align = 32;
        })
        editor.menu.AddItem("_", null);
        editor.menu.AddItem("图像尺寸-整体缩放", async () => {
            let sw = editor.drawCanvas.getWidth()
            let sh = editor.drawCanvas.getHeight()

            let d = new ValuesDialog("原尺寸: " + sw + " X " + sh,
                [
                    { name: "宽", defvalue: sw, type: ValueType.NUMBER },
                    { name: "高", defvalue: sh, type: ValueType.NUMBER },
                    { name: "插值", defvalue: false, type: ValueType.BOOL }
                ]);
            d.onCheck = (v) => {
                if (isNaN(v[0]) || isNaN(v[1]) || v[0] < 8 || v[0] > 2048 || v[1] < 8 || v[1] > 2048) {

                    throw new Error("尺寸错误，限制8~2048")
                }
                return true;
            }
            let nv = await d.Show();
            console.log("nv=" + JSON.stringify(nv));

            if (nv != null) {
                editor.drawCanvas.Resize_Scale(nv[0], nv[1], nv[2]);
                editor.priview.UpdateImgSize();
                editor.drawCanvas.RePaint();
            }
        });
        editor.menu.AddItem("图像尺寸-裁切画布", async () => {
            let sw = editor.drawCanvas.getWidth()
            let sh = editor.drawCanvas.getHeight()

            let d = new ValuesDialog("原尺寸: " + sw + " X " + sh,
                [
                    { name: "宽", defvalue: sw, type: ValueType.NUMBER },
                    { name: "高", defvalue: sh, type: ValueType.NUMBER },
                    { name: "方向", defvalue: { x: 0, y: 0 }, type: ValueType.DIR2 }
                ]);
            d.onCheck = (v) => {

                if (isNaN(v[0]) || isNaN(v[1]) || v[0] < 8 || v[0] > 2048 || v[1] < 8 || v[1] > 2048) {

                    throw new Error("尺寸错误，限制8~2048")
                }
                return true;
            }
            let nv = await d.Show();
            console.log("nv=" + JSON.stringify(nv));
            if (nv != null) {
                editor.drawCanvas.Resize_Cut(nv[0], nv[1], nv[2].x, nv[2].y);
                editor.priview.UpdateImgSize();
                editor.drawCanvas.RePaint();
            }
        });
        editor.menu.AddItem("_", null);
        editor.menu.AddItem("撤销 CTRL+Z", () => {
            this.history_Z(editor);
        });
        editor.menu.AddItem("重做 CTRL+A", () => {
            this.history_Y(editor);
        });
        editor.menu.AddItem("_", null);
        editor.menu.AddItem("关于", async () => {

            let msg: { "txt": string, "align": string }[] = [];
            msg.push({ "txt": "左侧可选择线宽、绘图工具、调色板颜色、模板", align: "left" });
            msg.push({ "txt": "", align: "left" });

            msg.push({ "txt": "绘图功能有：", align: "left" });
            msg.push({ "txt": "绘图：", align: "left" });
            msg.push({ "txt": " 1.铅笔", align: "left" });
            msg.push({ "txt": " 2.画线", align: "left" });
            msg.push({ "txt": " 3.画矩形", align: "left" });
            msg.push({ "txt": " 4.画圆：中心 + 半径", align: "left" });
            msg.push({ "txt": " 5.画圆：两点", align: "left" });
            msg.push({ "txt": " 6.画圆：画一个边界在矩形之内的圆", align: "left" });
            msg.push({ "txt": " 7.橡皮擦：擦除为透明色", align: "left" });
            msg.push({ "txt": " 8.吸色器，从画布中吸取一个颜色作为调色板选中色", align: "left" });
            msg.push({ "txt": " 9.选区功能，建立一个矩形选区，所有的操作都限制在选区内。", align: "left" });
            msg.push({ "txt": "10.填色功能：填充一个固定的颜色到画布中。", align: "left" });
            msg.push({ "txt": "11.填透明色功能：填充透明色到画布中。", align: "left" });
            msg.push({ "txt": "12.摆放模板功能：将选中的模板摆放到画布上。", align: "left" });
            msg.push({ "txt": "", align: "left" });

            msg.push({ "txt": "按住Ctrl 键有几个特殊功能", align: "left" });
            msg.push({ "txt": "1.Ctrl 键 点选调色板，设置透明背景下看到的颜色", align: "left" });
            msg.push({ "txt": "1.Ctrl 键 在画布上拖拽鼠标，当画布过大时快速移动位置", align: "left" });
            msg.push({ "txt": "1.Ctrl 键 在画布上滚动鼠标，快速改变显示倍率", align: "left" });


            let d = new MessageDialog("===TTEngine(躺平引擎) 像素编辑器==", msg);



            await d.Show();
        });
        let _b = new DOM.Button("===菜单===", async () => {

            let pos = editor.menu.GetElemCenter(_b._root);

            editor.menu.Show(pos.x, pos.y);
        });
        _b.Style_Fill();
        editor.group_func.AddChild(_b);

    }

}